﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace PigLatinTranslator
{
    public class Sentence
    {
        //Rule for Seperating Words
        const string WordSeperation = @"[a-z\'\-]*[a-z\'\-]";

        //Rule for retrieving the Special Characters
        const string SpecialCharacterCheck = @"([^\s\n!.?a-z-'])";

        //Rule for retrieving the Punctation
        const string PunctuationCheck = @"[!.?]";

        private string sentence;
        private MatchCollection words;
        private MatchCollection specialCharacters;
        int specialCharactersIndex = 0;
        private string punctuation;
        Translator translator;

        //Delegate that will be used to assign the proper translation
        private delegate string TranslateWord(string Word);

        //Constructor, takes a match of the sentece and converts to a string
        public Sentence(Match sentence)
        {
            this.sentence = sentence.ToString();
        }

        //Breaks up the sentence into word collection, SpecialChars and the punctuation
        private void BreakUpSentence()
        {
            //Uses regex to find matches for words , special chars and the punctuation
            words = Regex.Matches(sentence, WordSeperation, RegexOptions.IgnoreCase);
            specialCharacters = Regex.Matches(sentence, SpecialCharacterCheck, RegexOptions.IgnoreCase);
            punctuation = Regex.Match(sentence, PunctuationCheck).ToString();
        }

        //The beafiest part of the translator
        //This method breaks appart the sentence
        public string TranslateSentence(Translator translator)
        {
            StringBuilder sentenceCreator = new StringBuilder();
            this.translator = translator;

            BreakUpSentence();

            foreach (Match word in words)
            {
                //If there is another special char left to be appended
                //This  will run the conditions for proper placing of the special chars
                if (specialCharactersIndex < specialCharacters.Count)
                {
                    // Deals with the case of "can't".  Turns it into "an'tcay" or "an'tcay" to "can't"
                    if (specialCharacters[specialCharactersIndex].Index < word.Index)
                    {
                        specialCharactersIndex = DealWithSpecialCharacters(sentenceCreator, word);
                        continue;
                    }
                    //  Append the word
                    sentenceCreator.Append(translator.translateWord(word.ToString()));
                    //  check to see if the char should go directly infront of the word and there is another word
                    if (word.NextMatch().Success
                        && word.NextMatch().Index - 1 > specialCharacters[specialCharactersIndex].Index)
                    {
                        sentenceCreator.Append(specialCharacters[specialCharactersIndex].ToString());
                        sentenceCreator.Append(' ');
                        specialCharactersIndex++;
                        continue;
                    }
                    sentenceCreator.Append(' ');
                    continue;
                }
                sentenceCreator.Append(translator.translateWord(word.ToString()));
                sentenceCreator.Append(' ');
            }
            //  Remove an extra space from the end, if there is a sentence
            if (sentenceCreator.Length > 0)
                sentenceCreator.Remove(sentenceCreator.Length - 1, 1);
            sentenceCreator.Append(punctuation);
            return sentenceCreator.ToString();
        }

        private int DealWithSpecialCharacters(StringBuilder sentenceCreator, Match word)
        {
            sentenceCreator.Append(specialCharacters[specialCharactersIndex].ToString());
            //  If the special character is directly in front of the next word then add
            //  the word directly after the sentence
            if (specialCharacters[specialCharactersIndex].Index == word.Index - 1)
                sentenceCreator.Append(translator.translateWord(word.ToString()));
            sentenceCreator.Append(' ');
            specialCharactersIndex++;
            return specialCharactersIndex;
        }
    }
}
